package com.avalieme.teste;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import weka.classifiers.Evaluation;
import weka.classifiers.bayes.NaiveBayesUpdateable;
import weka.core.SerializationHelper;

import com.avalieme.classificadores.Classificador;
import com.avalieme.util.Constantes;

public class TesteAvalieMe {
	
	static Classificador classificadorBayesNet;
	
	public static void main(String[] args) throws Exception {
		if (args.length != 3 || (!args[2].equals("-on") && !args[2].equals("-pn"))) {
			System.err.println("Erro. Os dados devem ser: "
					+ "<dirOpinativo> <dirNeutro> -on OU <dirPositivo> <dirNegativo> -pn;");
			return;
		}

		String diretorioArquivos1 = args[0];
		String diretorioArquivos2 = args[1];
		String classe = args[2];
		Boolean opinativo = true;
		try {
			if (classe.equals("-on")) {
				classificadorBayesNet = (Classificador) SerializationHelper.read(Constantes.getModelo());
				addTests(diretorioArquivos1, Constantes.CLASSE_OPINATIVO);
				addTests(diretorioArquivos2, Constantes.CLASSE_NEUTRO);
			} else {
				classificadorBayesNet = (Classificador) SerializationHelper.read(Constantes.getModeloPN());
				addTests(diretorioArquivos1, Constantes.CLASSE_POSITIVO);
				addTests(diretorioArquivos2, Constantes.CLASSE_NEGATIVO);
				opinativo = false;
			}
		} catch (Exception e) {
			if (classe.equals("-on")) {
				classificadorBayesNet = new Classificador(new NaiveBayesUpdateable(),Constantes.getModelo(), false);
				addTests(diretorioArquivos1, Constantes.CLASSE_OPINATIVO);
				addTests(diretorioArquivos2, Constantes.CLASSE_NEUTRO);
			} else {
				classificadorBayesNet = new Classificador(new NaiveBayesUpdateable(),Constantes.getModeloPN(), true);
				addTests(diretorioArquivos1, Constantes.CLASSE_POSITIVO);
				addTests(diretorioArquivos2, Constantes.CLASSE_NEGATIVO);
				opinativo = false;
			}
		}

		System.out.println("- Resultados dos Testes:");
		output(classificadorBayesNet, opinativo);
	}

	private static void addTests(String diretorioArquivos, String classe)
			throws UnsupportedEncodingException, FileNotFoundException,
			IOException {
		File diretorio = new File(diretorioArquivos);

		System.out.println("Adicionando testes aos classificadores"
				+ " com os arquivos do diretorio <" + diretorioArquivos
				+ ">. Os tweets sao do tipo <" + classe + ">.");

		for (File f : diretorio.listFiles()) {
			if (f.isHidden() || !f.getName().endsWith(".in")) {
				continue;
			}

			BufferedReader bf = new BufferedReader(new InputStreamReader(
					new FileInputStream(f), "UTF-8"));
			while (true) {
				String tweet = bf.readLine();
				if (tweet == null) {
					break;
				}
				if (tweet.trim().equals("")) {
					continue;
				}
				tweet = tweet.toLowerCase();
				classificadorBayesNet.testar(tweet, classe);
			}
		}
	}

	private static void output(Classificador classifier, Boolean opinativo) {
		try {
			System.out.println("> Avaliando classificador: "+ classifier.getNomeClassificador() + " ...");
			Evaluation evaluation = classifier.evaluate();
			String acertos = "Acertos na classe ";
			String classe1 = opinativo ? acertos+Constantes.CLASSE_OPINATIVO+": " : acertos+Constantes.CLASSE_POSITIVO+": ";
			String classe2= opinativo ? acertos+Constantes.CLASSE_NEUTRO+": " : acertos+Constantes.CLASSE_NEGATIVO+": ";
			System.out.println(classe1+ evaluation.numTruePositives(0));
			System.out.println(classe2+ evaluation.numTruePositives(1));
			System.out.println(evaluation.toSummaryString());
		} catch (Exception e) {
			System.err.println("Erro na avaliação dos tweets: "+ e.getMessage());
		}
	}

}
